<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Arrays in Ruby</title>
<link rel="stylesheet" href="/cfg/format.css" type="text/css">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="keywords" content="Ruby, learn Ruby, arrays, tutorial, programming language">
<meta name="description" content="In this part of the Ruby tutorial we will cover arrays.">
<meta name="language" content="en">
<meta name="author" content="Jan Bodnar">
<meta name="distribution" content="global">

<script type="text/javascript" src="/lib/jquery.js"></script>
<script type="text/javascript" src="/lib/common.js"></script>

</head>

<body>

<div class="container2">

<div id="wide_ad" class="ltow">
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* 160x600, August 2011 */
google_ad_slot = "2484182563";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>


<div class="content2">


<a href="/" title="Home">Home</a>&nbsp;
<a href="..">Contents</a>



<h1>Arrays in Ruby</h1>

<p>
In this part of the Ruby tutorial, we will cover arrays. Arrays are
ordered collections of objects. 
</p>

<div class="big_hor">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-9706709751191532";
/* big_horizontal */
google_ad_slot = "2904953388";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>

<p>
A variable can hold only one item at a time. Arrays can hold 
multiple items. These items are called elements of the array. Arrays can
hold objects of any data type. Each element can be referred to by an index. 
Arrays are zero based. The index of the first element is zero. 
</p>

<p>
Note that Ruby arrays are very different from arrays in languages like C, C++ or Java.
</p>


<pre class="code">
#!/usr/bin/ruby

nums = [1, 2, 3, 4, 5]

nums.each do |num|
    puts num
end
</pre>

<p>
Our first example will create an array of five integers. The elements
of the array are printed to the console. 
</p>

<pre class="explanation">
nums = [1, 2, 3, 4, 5]
</pre>

<p>
This line creates an array of five integers. Elements are separated by 
commas and placed between square brackets. 
</p>

<pre class="explanation">
nums.each do |num|
    puts num
end
</pre>

<p>
We go through the array with the <code>each</code> method and print
each element to the console. 
</p>

<pre>
$ ./array.rb
1
2
3
4
5
</pre>

<p>
Output. 
</p>

<h2>Array creation</h2>

<p>
An array in Ruby is an object. Arrays can be instantiated 
with the <code>new</code> method. 
</p>

<pre class="code">
#!/usr/bin/ruby

nums = Array.new

nums.push 1
nums.push 2
nums.push 3
nums.push 4
nums.push 5

puts nums
</pre>

<p>
In the script we first create a nums array. Then
we add five integers to it.
</p>

<pre class="explanation">
nums = Array.new
</pre>

<p>
An array object is created. 
</p>

<pre class="explanation">
nums.push 1
</pre>

<p>
The <code>push</code> method appends an item to the end
of the array.
</p>

<hr class="btm">

<p>
We will continue with the array object creation
using the <code>new</code> method. 
</p>

<pre class="code">
#!/usr/bin/ruby

a1 = Array.new 
a2 = Array.new 3
a3 = Array.new 6, "coin"
a4 = Array.new [11]
a5 = Array.new (15) {|e| e*e}

puts [a1, a2, a3, a4, a5].inspect
</pre>

<p>
The <code>new</code> method of the Array class may take
some options. 
</p>

<pre class="explanation">
a1 = Array.new 
</pre>

<p>
An empty array is created. We are supposed to fill it with
data later on.
</p>

<pre class="explanation">
a2 = Array.new 3
</pre>

<p>
Here we create an array of three nil objects. 
</p>

<pre class="explanation">
a3 = Array.new 6, "coin"
</pre>

<p>
An array containing six "coin" strings is created. The first
option is the size of the array. The second option is the object
to fill the array. 
</p>

<pre class="explanation">
a4 = Array.new [11]
</pre>

<p>
The fourth array will have one item. 
</p>

<pre class="explanation">
a5 = Array.new (15) {|e| e*e}
</pre>

<p>
We create an array with 15 elements. Each element is created
in the block. There we compute a sequence of squared integers.
</p>

<pre class="explanation">
puts [a1, a2, a3, a4, a5].inspect
</pre>

<p>
We put all our arrays into one array. Arrays may be put into other
arrays. Then we call the <code>inspect</code> method on the array. 
This will call the method on all its elements. The 
<code>inspect</code> method returns the string representation of
the array. This is useful, when we need to quickly check the contents
of an array.
</p>

<pre>
$ ./arraynew.rb
[[], [nil, nil, nil], ["coin", "coin", "coin", "coin", "coin", "coin"], 
[11], [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196]]
</pre>

<p>
We can see the contents of all the arrays created.
</p>


<hr class="btm">

<p>
The following script shows various ways to create
arrays in Ruby.
</p>

<pre class="code">
#!/usr/bin/ruby

integers = [1, 2, 3, 4, 5]
animals = %w( donkey dog cat dolphin eagle )
weights = Array.new
weights &lt;&lt; 4.55 &lt;&lt; 3.22 &lt;&lt; 3.55 &lt;&lt; 8.55 &lt;&lt; 3.23

puts integers.inspect
puts animals.inspect
puts weights.inspect
</pre>

<p>
We create three arrays of integers, strings and decimals. 
</p>

<pre class="explanation">
integers = [1, 2, 3, 4, 5]
</pre>

<p>
This line creates an array having 5 integers. 
This is the classic array creation. Elements of the array are put between
square brackets and separated by commas. 
</p>

<pre class="explanation">
animals = %w( donkey dog cat dolphin eagle )
</pre>

<p>
The code line creates a string array with five elements. 
In this mode, we save some typing. We do not use the commas
and double quotes. 
</p>

<pre class="explanation">
weights = Array.new
weights &lt;&lt; 4.55 &lt;&lt; 3.22 &lt;&lt; 3.55 &lt;&lt; 8.55 &lt;&lt; 3.23
</pre>

<p>
In the third way, there are two steps. Array object creation and initialization
with data. This is a formal array creation. The above ways were in fact shorthands
for this notation.
</p>

<pre class="explanation">
puts integers.inspect
</pre>

<p>
The <code>inspect</code> method prints the string representation of the array to 
the terminal. 
</p>

<pre>
$ ./creation.rb
[1, 2, 3, 4, 5]
["donkey", "dog", "cat", "dolphin", "eagle"]
[4.55, 3.22, 3.55, 8.55, 3.23]
</pre>

<p>
Output of the code example. 
</p>

<hr class="btm">

<p>
Array items are not limited to numbers and strings. Arrays can
contain all Ruby data types. 
</p>

<pre class="code">
#!/usr/bin/ruby

class Empty
  
end

nums = [1, 2, 3, 4, 5]

various = [1, -1, "big", 3.4, Empty.new, nums, :two]

puts various.inspect
</pre>

<p>
We put various Ruby objects inside the various array. 
</p>

<pre class="explanation">
various = [1, -1, "big", 3.4, Empty.new, nums, :two]
</pre>

<p>
The array contains numbers, a string, a custom object, 
another array and a symbol. 
</p>

<pre>
$ ./arrayobjects.rb                                                                                 
[1, -1, "big", 3.4, #&lt;Empty:0x987f704&gt;, [1, 2, 3, 4, 5], :two] 
</pre>

<p>
Running the arrayobjects.rb example, we receive this output.
</p>

<hr class="btm">

<p>
The last example showed a nested array; an array within another array. In Ruby,
it is possible to nest arrays into arrays. 
</p>

<pre class="code">
#!/usr/bin/ruby

numbers = [1, 2, 3, [2, 4, 6, [11, 12]]]

puts numbers.length
puts numbers[0], numbers[1]

puts numbers[3][0]
puts numbers[3][1]

puts numbers[3][3][0]
puts numbers[3][3][1]

puts numbers.flatten!.inspect
</pre>

<p>
The array [11, 12] is nested within the [2, 4, 6, ...] array, which
is also nested in the [1, 2, 3, ...] array. 
</p>

<pre class="explanation">
puts numbers.length
</pre>

<p>
The <code>length</code> method returns 4. The inner array is counted 
as one element. 
</p>

<pre class="explanation">
puts numbers[0], numbers[1]
</pre>

<p>
The [] characters serve in this context the purpose of accessing
array elements. The above line returns the first and the second
element (numbers 1 and 2) of the numbers array. The numbers within
the square brackets are indexes to the array. The first index is 0, 
which returns the first element. 
</p>

<pre class="explanation">
puts numbers[3][0]
puts numbers[3][1]
</pre>

<p>
Here we access elements from the nested array. The [3] grabs the 
fourth element, which is an array, [2, 4, 6, [11, 12]]. The
[3][0] returns the first element of the inner array, which is number
2 in our case. In a similar fashion, the [3][1] returns the second
element of the inner array, the number 4. 
</p>

<pre class="explanation">
puts numbers[3][3][0]
puts numbers[3][3][1]
</pre>

<p>
Now we go even deeper. We access the elements of the innermost array. 
The [3][3] return the [11, 12] array. And from this array we get the
first (11) and the second (12) element. 
</p>

<pre class="explanation">
puts numbers.flatten!.inspect
</pre>

<p>
The <code>flatten!</code> method flattens the array. It takes all
elements from the inner arrays and creates a new one, without any
inner arrays. 
</p>

<pre>
$ ./arrayofarrays.rb
4
1
2
2
4
11
12
[1, 2, 3, 2, 4, 6, 11, 12]
</pre>

<p>
This is the output of the code example. 
</p>


<h2>Printing array contents</h2>

<p>
A common job is to print array elements to to console. 
We have several ways to accomplish this task. 
</p>

<pre class="code">
#!/usr/bin/ruby

integers = [1, 2, 3, 4, 5]

puts integers
puts integers.inspect

integers.each do |e|
    puts e
end
</pre>

<p>
In this script, we print all the elements of an array three times. 
</p>

<pre class="explanation">
puts integers
</pre>

<p>
The array as a parameter to the puts/print method is the simplest way to 
print the contents of the array. Each element is printed on a separate line. 
</p>

<pre class="explanation">
puts integers.inspect
</pre>

<p>
Using the <code>inspect</code> method, the output is more readable. The line
prints the string representation of the array to the terminal. 
</p>

<pre class="explanation">
integers.each do |e|
    puts e
end
</pre>

<p>
The <code>each</code> method calls a block once for each element in array, 
passing that element as a parameter. We simply use the <code>puts</code> 
method on each element. 
</p>

<pre>
$ ./printarray1.rb
1
2
3
4
5
[1, 2, 3, 4, 5]
1
2
3
4
5
</pre>

<p>
The array is printed three times to the console. 
</p>

<hr class="btm">

<p>
In the second example, we provide additional two ways to 
print array elements. 
</p>

<pre class="code">
#!/usr/bin/ruby

integers = [1, 2, 3, 4, 5]

integers.length.times do |idx|
    puts integers[idx]
end

integers.each_with_index do |num, idx|
    puts "value #{num} has index #{idx}"
end
</pre>

<p>
In the first case, we use the combination of the <code>length</code> and
<code>times</code> method. In the second case, we use the <code>each_with_index</code>
method. 
</p>

<pre class="explanation">
integers.length.times do |idx|
    puts integers[idx]
end
</pre>

<p>
The <code>length</code> method returns the size of the array. The <code>times</code> 
method iterates the following block length times, passing in values from 0 to length-1.
These numbers serve as indexes to the array in question. 
</p>

<pre class="explanation">
integers.each_with_index do |num, idx|
    puts "value #{num} has index #{idx}"
end
</pre>

<p>
The <code>each_with_index</code> iterates the array and passes the element
and its index to the given block. This way we can easily print the element
and its index in one shot. 
</p>

<pre>
$ ./printarray2.rb
1
2
3
4
5
value 1 has index 0
value 2 has index 1
value 3 has index 2
value 4 has index 3
value 5 has index 4
</pre>

<p>
Output of the example. 
</p>



<h2>Reading array elements</h2>

<p>
In this section, we will read data from the arrays. 
</p>

<pre class="code">
#!/usr/bin/ruby

lts = %w{ a b c d e f g h}

puts lts.first
puts lts.last
puts lts.at(3)
</pre>

<p>
In the first example, we show three simple methods for data
retrieval. 
</p>

<pre class="explanation">
puts lts.first
puts lts.last
</pre>

<p>
The <code>first</code> method reads the first element of the array.
The <code>last</code> method reads the last element of the array.
</p>

<pre class="explanation">
puts lts.at(3)
</pre>

<p>
The <code>at</code> method returns the array element having a
specific index. This line reads the fourth element of the array.
</p>

<pre>
$ ./retrieval.rb
a
h
d
</pre>

<p>
Output of the example.
</p>

<hr class="btm">

<p>
The [] characters can be used to access data. This is
the traditional way of accessing data in arrays, used by many other programming
languages. It saves some typing. 
</p>

<pre class="code">
#!/usr/bin/ruby

lts = %w{ a b c d e f g h }

puts lts[0]
puts lts[-1]
puts lts[0, 3].inspect
puts lts[2..6].inspect
puts lts[2...6].inspect
</pre>

<p>
We show five examples of reading data using the [] characters. 
</p>

<pre class="explanation">
puts lts[0]
puts lts[-1]
</pre>

<p>
We get the first and the last item of the array.
We put the index number of an item between the [] characters.
The first item has index 0, the last item has index -1. 
</p>

<pre class="explanation">
puts lts[0, 3].inspect
</pre>

<p>
When we have two numbers between the square brackets, the first is
the start index and the second is the length. In this code line, 
we return 3 elements starting from index 0. Note that the <code>inspect</code>
method is optional and it is only used to produce more readable output. 
</p>

<pre class="explanation">
puts lts[2..6].inspect
puts lts[2...6].inspect
</pre>

<p>
We can use range operator inside the square brackets. In the first line
we read elements from index 2 to 6, in the second line elements from
2 to 5. 
</p>

<hr class="btm">

<p>
Next we will demonstrate the <code>values_at</code> method. The advantage
of this method is that we can place multiple indexes between the [] characters
to get various elements. 
</p>

<pre class="code">
#!/usr/bin/ruby

lts = %w{ a b c d e f g h}

puts lts.values_at(1..5).inspect
puts lts.values_at(1, 3, 5).inspect
puts lts.values_at(1, 3, 5, 6, 8).inspect
puts lts.values_at(-1, -3).inspect
</pre>

<p>
The <code>values_at</code> method returns an array containing the 
elements which corresponding to the given selector(s). The <code>inspect</code>
method is optional. It is used to get a more readable output. 
</p>

<pre class="explanation">
puts lts.values_at(1..5).inspect
</pre>

<p>
This code line returns elements which have indexes 1 to 5.  
</p>

<pre class="explanation">
puts lts.values_at(1, 3, 5).inspect
</pre>

<p>
Here we read elements with indexes 1, 3 and 5.  
</p>

<pre class="explanation">
puts lts.values_at(1, 3, 5, 6, 8).inspect
</pre>

<p>
We put as many indexes as we want. If there is no
element with the specific index, we get nil.  
</p>

<pre class="explanation">
puts lts.values_at(-1, -3).inspect
</pre>

<p>
Negative indexes return elements from the end of the
array. 
</p>

<pre>
$ ./retrieval3.rb
["b", "c", "d", "e", "f"]
["b", "d", "f"]
["b", "d", "f", "g", nil]
["h", "f"]
</pre>

<p>
This is the output of the script. 
</p>

<hr class="btm">

<p>
We will use the <code>fetch</code> method to read data
from an array.
</p>

<pre class="code">
#!/usr/bin/ruby

lts = [0, 1, 2, 3, 4, 5, 6]

puts lts.fetch(0)
puts lts.fetch(-2)
puts lts.fetch(8, 'undefined')
puts lts.fetch(8) { |e| -2*e }
</pre>

<p>
We show several forms of using the <code>fetch</code> method.
</p>

<pre class="explanation">
puts lts.fetch(0)
puts lts.fetch(-2)
</pre>

<p>
The first line prints the first element from the array. The second
line prints the second element from the end of the array.
</p>

<pre class="explanation">
puts lts.fetch(8, 'undefined')
</pre>

<p>
The third form of the <code>fetch</code> method returns the element
with the given index. If the index lies outside the array elements, the
method returns the default value, 'undefined' in our case. Without the
second parameter, the <code>fetch</code> method throws an 
<code>IndexError</code>.
</p>

<pre class="explanation">
puts lts.fetch(8) { |e| -2*e }
</pre>

<p>
In the last form of the <code>fetch</code> method, we have a block.
In case a value with a given index is not found, the method returns
a value of invoking the block, passing in the index. 
</p>

<pre>
$ ./retrieval4.rb
0
5
undefined
-16
</pre>

<p>
Output of the script. 
</p>

<hr class="btm">

<p>
We will show the usage of the <code>take</code> and
<code>take_while</code> methods. 
</p>

<pre class="code">
#!/usr/bin/ruby

lts = %w{ a b c d e f g h}


puts lts.take(4).inspect

lts2 = lts.take_while { |e| e &lt; 'f' }
puts lts2.inspect
</pre>

<p>
The <code>take n</code> method returns the first n
elements of the array. The <code>take_while</code> method passes 
elements to the block until the block returns nil or false, 
then stops iterating and returns an array of all prior elements.
</p>


<pre class="explanation">
puts lts.take(4).inspect
</pre>

<p>
Here we return the first four elements of the array. 
</p>

<pre class="explanation">
lts2 = lts.take_while { |e| e &lt; 'f' }
puts lts2.inspect
</pre>

<p>
Here we create a new array from the original array. In the new array
we have all characters that come before the 'f' character.  
</p>

<pre>
$ ./retrieval5.rb
["a", "b", "c", "d"]
["a", "b", "c", "d", "e"]
</pre>

<p>
Output.
</p>

<hr class="btm">

<p>
The <code>slice</code> method is identical to the []
characters. The method returns one or more elements
from the array. 
</p>

<pre class="code">
#!/usr/bin/ruby

lts = %w{ a b c d e f g h}

puts lts.slice(0)
puts lts.slice(-1)
puts lts.slice(0, 3).inspect
puts lts.slice(2..6).inspect
puts lts.slice(2...6).inspect
</pre>

<p>
We present five examples of the <code>slice</code> method. 
</p>


<pre class="explanation">
puts lts.slice(0)
puts lts.slice(-1)
</pre>

<p>
These forms of the <code>slice</code> method return one array
element. The first code line returns the first element, the second
line returns the last element of the lts array.  
</p>

<pre class="explanation">
puts lts.slice(0, 3).inspect
</pre>

<p>
The first parameter is the start index and the second parameter is 
the length. In this code line, we return 3 elements starting from index 0. 
</p>

<pre class="explanation">
puts lts.slice(2..6).inspect
puts lts.slice(2...6).inspect
</pre>

<p>
We can use range operator with the <code>slice</code> method. In the first line we 
read elements from index 2 to 6, in the second line elements from 2 to 5. 
</p>

<pre>
$ ./retrieval6.rb
a
h
["a", "b", "c"]
["c", "d", "e", "f", "g"]
["c", "d", "e", "f"]
</pre>

<p>
The <code>slice</code> method returns portions of the array. One or more elements
of the array. 
</p>


<hr class="btm">

<p>
It is possible to select a random number from an array. Ruby
has a <code>sample</code> method for this. 
</p>

<pre class="code">
#!/usr/bin/ruby

lts = %w{ a b c d e f g h}

puts lts.sample
puts lts.sample(3).inspect
</pre>

<p>
The <code>sample</code> method comes in two forms. 
In the first form, we select a random element. In the
second form, we select n random elements from the array.
</p>

<pre>
$ ./random.rb
b
["c", "f", "d"]
$ ./random.rb
d
["c", "d", "e"]
</pre>

<p>
Running the example twice gives different results. 
</p>


<h2>Working with arrays</h2>

<p>
In the following examples, we will introduce several Ruby 
array methods.
</p>

<pre class="code">
#!/usr/bin/ruby

num1 = [1, 2, 3, 4, 5]
num2 = [6, 7, 8, 9, 10]

puts num1 + num2 
puts num1.concat num2
</pre>

<p>
We have two arrays. We add these two arrays. 
</p>

<pre class="explanation">
puts num1 + num2 
puts num1.concat num2
</pre>

<p>
There are two ways to add arrays. We can use the + operator
or the <code>concat</code> method. The result is the same. 
</p>

<hr class="btm">

<p>
Ruby has plenty of methods for working with arrays. For example,
the <code>length</code> method returns the number of elements 
in the array. 
</p>

<pre class="code">
#!/usr/bin/ruby

lts = %w{ a b c d e f}

puts lts.inspect
puts "Array has #{lts.length} elements"
puts "The first element is #{lts.first}"
puts "The last element is #{lts.last}"

puts lts.eql? lts.dup
puts lts.eql? lts.dup.delete_at(0)

lts.clear
puts lts.inspect
puts lts.empty?
</pre>

<p>
In the above script, we introduce seven new methods. 
</p>

<pre class="explanation">
puts "Array has #{lts.length} elements"
</pre>

<p>
The <code>lenght</code> method determines the size of the array.
</p>

<pre class="explanation">
puts "The first element is #{lts.first}"
puts "The last element is #{lts.last}"
</pre>

<p>
Here we get the first and the last element of the array. 
</p>

<pre class="explanation">
puts lts.eql? lts.dup
</pre>

<p>
The <code>eql?</code> method figures out if two arrays are
equal. In our case the line returns true. The <code>dup</code>
method creates a shallow copy of an object. It is inherited from 
the <code>Object</code> parent. 
</p>

<pre class="explanation">
puts lts.eql? lts.dup.delete_at(0)
</pre>

<p>
The <code>delete_at</code> method deletes the first element
of the array. This time the two arrays do not equal. 
</p>

<pre class="explanation">
lts.clear
</pre>

<p>
The <code>clear</code> method deletes all elements from the
array. 
</p>

<pre class="explanation">
puts lts.empty?
</pre>

<p>
The <code>empty?</code> method checks, whether the array is
empty. In our case the code line returns true, because we have
just deleted all its elements. 
</p>

<pre>
$ ./basics.rb
["a", "b", "c", "d", "e", "f"]
Array has 6 elements
The first element is a
The last element is f
true
false
[]
true
</pre>

<p>
Output. 
</p>

<hr class="btm">

<p>
Some Ruby array methods end with an exclamation mark. This is a Ruby 
idiom. The exclamation mark tells the programmer, that the method will
modify data. The exclamation mark itself does not have any effect. 
It is merely a naming convention. 
</p>

<pre class="code">
#!/usr/bin/ruby

chars = %w{a b c d e}

reversed_chars = chars.reverse
puts reversed_chars.inspect
puts chars.inspect

reversed_chars = chars.reverse!
puts reversed_chars.inspect
puts chars.inspect
</pre>

<p>
Ruby has, among others, two similar methods, the <code>reverse</code> method
and <code>reverse!</code> method. These two methods change the order of
the elements, they reverse it. The difference is, that the <code>reverse</code>
method returns a reversed array and leaves the original array intact, while
the <code>reverse!</code> method both modifies the contents of the original array and
returns a new reversed array.
</p>

<pre>
$ ./twotypes.rb
["e", "d", "c", "b", "a"]
["a", "b", "c", "d", "e"]
["e", "d", "c", "b", "a"]
["e", "d", "c", "b", "a"]
</pre>

<p>
We can clearly see, that the first two arrays are different. The third
and fourt arrays are same. 
</p>

<hr class="btm">

<p>
A few other methods will be presented in the coming code example. 
</p>

<pre class="code">
#!/usr/bin/ruby

numbers = [1, 2, 2, 2, 3, 4, 5, 8, 11]

puts numbers.index 2
puts numbers.index 11
puts numbers.rindex 2

puts numbers.include? 3
puts numbers.include? 10

puts numbers.join '-'
puts numbers.uniq!.inspect
</pre>

<p>
We introduce additional five methods. 
</p>

<pre class="explanation">
puts numbers.index 2
puts numbers.index 11
</pre>

<p>
The <code>index</code> method returns the index of the
array element. It returns the index of the first element
from the left. The first line returns 1, which is the index
of the first 2 in the array. There is only one 11 in the array
and its index is 8. 
</p>

<pre class="explanation">
puts numbers.rindex 2
</pre>

<p>
The <code>rindex</code> returns the index of the first element
from the right. In our case, the rightmost 2 has index 3. 
</p>

<pre class="explanation">
puts numbers.include? 3
puts numbers.include? 10
</pre>

<p>
The <code>include?</code> method checks, if an element is present
in the array. The first line returns true; 3 is present. 
The second line returns false; there is no 10 in our array. 
By convention, Ruby methods ending with question mark return a boolean value. 
Again, the question mark has no effect on the array. It is merely a hint
for the programmer. 
</p>

<pre class="explanation">
puts numbers.join '-'
</pre>

<p>
The <code>join</code> method returns a string created from the
array elements, separated by a provided separator. 
</p>

<pre class="explanation">
puts numbers.uniq!.inspect
</pre>

<p>
The <code>uniq!</code> method removes duplicate elements from 
the array. We have three times number 2 in the array. After the
method call, there will be only one 2 left. 
</p>

<pre>
$ ./methods2.rb 
1
8
3
true
false
1-2-2-2-3-4-5-8-11
[1, 2, 3, 4, 5, 8, 11]
</pre>

<p>
Output of the example. Notice the product of the <code>join</code> method.
It is a string, in which the numbers of the array are joined by 
the - character.
</p>

<h2>Modifying arrays</h2>

<p>
In this section, we will look closer at the methods, that modify an
array. Basically, we will do various insertion and deletion operations
on the arrays. 
</p>

<pre class="code">
#!/usr/bin/ruby

lts = []

lts.insert 0, 'E', 'F', 'G'
lts.push 'H'
lts.push 'I', 'J', 'K'
lts &lt;&lt; 'L' &lt;&lt; 'M' 
lts.unshift 'A', 'B', 'C'
lts.insert(3, 'D')
    
puts lts.inspect
</pre>

<p>
We start with an empty array. We build the array using different
insertion methods. 
</p>

<pre class="explanation">
lts.insert 0, 'E', 'F', 'G'
</pre>

<p>
The <code>insert</code> method inserts three elements into the
lts array. The first letter has index 0, the second 1 and the
third 3. 
</p>

<pre class="explanation">
lts.push 'H'
lts.push 'I', 'J', 'K'
</pre>

<p>
The <code>push</code> method appends the elements to the array. 
We can append one or more elements. 
</p>

<pre class="explanation">
lts &lt;&lt; 'L' &lt;&lt; 'M' 
</pre>

<p>
The &lt;&lt; is a synonym for the <code>push</code> method. It appends
an element to the array. This operator/method can be called in a chain. 
</p>

<pre class="explanation">
lts.unshift 'A', 'B', 'C'
</pre>

<p>
The <code>unshift</code> method prepends elements to the front of the array.
</p>

<pre class="explanation">
lts.insert(3, 'D')
</pre>

<p>
In this case, the <code>insert</code> method inserts the 'D' character at
a specific index. 
</p>

<pre>
$ ./insertion.rb
["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M"]
</pre>

<p>
Using the above mentioned array insertion methods, we have built this
array of uppercase letters. 
</p>

<hr class="btm">

<p>
There are several methods for deleting array elements.
</p>

<pre class="code">
#!/usr/bin/ruby

lts = %w{ a b c d e f g h}

lts.pop
lts.pop

puts lts.inspect

lts.shift
lts.shift

puts lts.inspect

lts.delete_at(0)
lts.delete('d')

puts lts.inspect

puts lts.clear
puts lts.inspect
</pre>

<p>
In this script we demonstrate five methods that
delete elements from an array. 
</p>

<pre class="explanation">
lts = %w{ a b c d e f g h}
</pre>

<p>
We have an array of 8 elements. 
</p>

<pre class="explanation">
lts.pop
</pre>

<p>
The <code>pop</code> method removes the last element from the
array. 
</p>

<pre class="explanation">
lts.shift
</pre>

<p>
The <code>shift</code> method removes the first element from the array. 
</p>

<pre class="explanation">
lts.delete_at(0)
</pre>

<p>
The <code>delete_at</code> deletes an element at a specific 
position. We delete the first element of the remaining elements.
</p>

<pre class="explanation">
puts lts.clear
</pre>

<p>
The <code>clear</code> method clears all the elements from the array.
</p>

<pre class="explanation">
lts.delete('d')
</pre>

<p>
The <code>delete</code> method deletes a specific item from the array.
</p>

<pre>
$ ./deletion.rb
["a", "b", "c", "d", "e", "f"]
["c", "d", "e", "f"]
["e", "f"]
[]
</pre>

<p>
Output of the example. 
</p>

<hr class="btm">

<p>
So far we have worked with methods (with an exception of the <code>clear</code> method)
that modified an array by adding or deleting an item a time. Ruby has methods that
affect multiple array items at once. 
</p>

<pre class="code">
#!/usr/bin/ruby

nms = [2, -1, -4, 0, 4, 3, -2, 3, 5]

nms.delete_if { |x| x &lt; 0 }

puts nms.inspect
</pre>

<p>
The example introduces a <code>delete_if</code> method, that
deletes all items that meet a condition presented in the block. 
</p>

<pre class="explanation">
nms.delete_if { |x| x &lt; 0 }
</pre>

<p>
This line deletes all negative numbers from the array.
</p>

<pre>
$ ./delete_if.rb
[2, 0, 4, 3, 3, 5]
</pre>

<p>
We have dropped all negative numbers from the nms array.
</p>

<hr class="btm">

<p>
We present another two methods, that process multiple
array items. 
</p>

<pre class="code">
#!/usr/bin/ruby

lts = %w{ a b c d e f g}

puts lts.inspect

lts.reject! do |e|
    e =~ /[c-y]/
end

puts lts.inspect

lts.replace(["x", "y", "z"])
puts lts.inspect
</pre>

<p>
We use two methods, the <code>reject!</code> method and the
<code>replace</code> method. 
</p>

<pre class="explanation">
lts.reject! do |e|
    e =~ /[c-y]/
end
</pre>

<p>
The <code>reject!</code> method removes all array items, that meet
a specific condition inside the block. In our case, we delete all
letters that comply with the regular expression; any letter from 
c to y.
</p>

<pre class="explanation">
lts.replace(["x", "y", "z"])
</pre>

<p>
The <code>replace</code> method will replace items with other given
items. It truncates or expands the array if necessary. 
</p>

<pre>
$ ./modify.rb 
["a", "b", "c", "d", "e", "f", "g"]
["a", "b"]
["x", "y", "z"]
</pre>

<p>
Output of the <code>modify.rb</code> example. 
</p>

<h2>Set operations</h2>

<p>
In this section, we present set operations applicable
on Ruby arrays. In mathematics a set is a is a collection 
of distinct objects.
</p>

<pre class="code">
#!/usr/bin/ruby

A = [1, 2, 3, 4, 5]
B = [4, 5, 6, 7, 8]

union = A | B
isect = A &amp; B
diff1  = A - B
diff2  = B - A
sdiff = (A - B) | (B - A)

puts "Union of arrays: #{union}"
puts "Intersection of arrays: #{isect}"
puts "Difference of arrays A - B: #{diff1}"
puts "Difference of arrays B - A: #{diff2}"    
puts "Symmetric difference of arrays: #{sdiff}" 
</pre>

<p>
In the above script, we demonstrate several set operations,
union, intersection, difference and symmetric difference. 
</p>

<pre class="explanation">
nums1 = [1, 2, 3, 4, 5]
nums2 = [4, 5, 6, 7, 8]
</pre>

<p>
We define two arrays of integers. Both are sets, because each element
in the array is presented only once. The two arrays have two numbers in 
common, the 4 and 5. 
</p>

<pre class="explanation">
union = nums1 | nums2
</pre>

<p>
This operation is a union of two arrays. The two arrays are added. Each element
in the final array is presented only once. 
</p>

<pre class="explanation">
isect = A &amp; B
</pre>

<p>
The above operations is intersection of two sets. The outcome is an array
having elements which are present in both arrays. In our case, 4 and 5. 
</p>

<pre class="explanation">
diff1  = A - B
diff2  = B - A
</pre>

<p>
Here we have two difference operations. Also called complements. In the first line,
we get all elements that are present in A and not present in B. In the second line,
we get all elements which are members of B and not A. 
</p>

<pre class="explanation">
sdiff = (A - B) | (B - A)
</pre>

<p>
Here we have a symmetric difference. A symmetric difference gives elements that
are either in A or in B, but not in both sets. 
</p>

<pre>
$ ./setoperations.rb
Union of arrays: [1, 2, 3, 4, 5, 6, 7, 8]
Intersection of arrays: [4, 5]
Difference of arrays A - B: [1, 2, 3]
Difference of arrays B - A: [6, 7, 8]
Symmetric difference of arrays: [1, 2, 3, 6, 7, 8]
</pre>

<p>
Output of the example. 
</p>


<h2>The select, collect, map methods</h2>

<p>
In the next example, we will present three methods. The
<code>select</code>, <code>collect</code> and <code>map</code> methods. 
</p>

<pre class="code">
#!/usr/bin/ruby

nums = [1, 3, 2, 6, 7, 12, 8, 15]

selected = nums.select do |e|
    e &gt; 10
end

puts selected.inspect

collected = nums.collect do |e|
    e &lt; 10
end

puts collected.inspect

mapped = nums.map do |e|
    e*2
end

puts mapped.inspect
</pre>

<p>
All these methods execute mass operations on the elements of an array.
</p>

<pre class="explanation">
selected = nums.select do |e|
    e &gt; 10
end
</pre>

<p>
In the above code, we create a new array using the <code>select</code>
method. For the newly created array, we choose elements comply with
the condition inside the block. In our case, we select all elements that
are greater than 10. 
</p>

<pre class="explanation">
collected = nums.collect do |e|
    e &lt; 10
end
</pre>

<p>
The <code>collect</code> method works a bit differently. It invokes
the appended block for each element and returns the value from the 
block. The new array contains true, false values. 
</p>

<pre class="explanation">
mapped = nums.map do |e|
    e*2
end
</pre>

<p>
The <code>map</code> method is similar to the <code>collect</code> method.
In the above lines we create a new array from the existing array. Each
element is multiplied by 2. 
</p>

<pre>
$ ./mass.rb
[12, 15]
[true, true, true, true, true, false, true, false]
[2, 6, 4, 12, 14, 24, 16, 30]
</pre>

<p>
These are the newly created arrays. 
</p>


<h2>Ordering elements</h2>

<p>
Finally, we will be ordering elements in our array. 
</p>

<pre class="code">
#!/usr/bin/ruby

planets = %w{ Mercury Venus Earth Mars Jupiter
                Saturn Uranus Neptune Pluto }
               
puts "#{planets.sort}"                
puts "#{planets.reverse}"
puts "#{planets.shuffle}"
</pre>

<p>
The example uses three Ruby array methods to reorganize elements
in the array. 
</p>

<pre class="explanation">
puts "#{planets.sort}"  
</pre>

<p>
The <code>sort</code> method alphabetically sort the array elements. 
</p>

<pre class="explanation">
puts "#{planets.reverse}"
</pre>

<p>
The <code>reverse</code> method returns a new array with all elements
in a reverse order. 
</p>

<pre class="explanation">
puts "#{planets.shuffle}"
</pre>

<p>
The <code>shuffle</code> method randomly reorganizes the array elements. 
</p>

<pre>
$ ./ordering.rb
["Earth", "Jupiter", "Mars", "Mercury", "Neptune", "Pluto", "Saturn", "Uranus", "Venus"]
["Pluto", "Neptune", "Uranus", "Saturn", "Jupiter", "Mars", "Earth", "Venus", "Mercury"]
["Earth", "Jupiter", "Mercury", "Saturn", "Mars", "Venus", "Uranus", "Pluto", "Neptune"]
</pre>

<p>
A sample output of the code example. 
</p>


<p>
In this chapter, we worked with Ruby arrays. 
</p>


<div class="botNav, center">
<span class="botNavItem"><a href="/">Home</a></span> ‡ <span class="botNavItem"><a href="..">Contents</a></span> ‡ 
<span class="botNavItem"><a href="#">Top of Page</a></span>
</div>


<div class="footer">
<div class="signature">
<a href="/">ZetCode</a> last modified December 14, 2011 <span class="copyright">&copy; 2007 - 2013 Jan Bodnar</span>
</div>
</div>

</div> <!-- content -->

</div> <!-- container -->

</body>
</html>

